const FormData = require("form-data");
const fs = require("fs");
const url = require("url");
const path = require("path");
const util = require("util");
const Toolbox = require("../tool/toolbox");
const runParallel = require("run-parallel-limit");


/**
 * @description 大小限制：20MB以下
 * @returns {Promise<{ok:Boolean,msg:String,data:{
  * image_url:String
  * }}>}
  * @param {String} file_path 
  */
function uploadFile(file_path) {
  return new Promise(resolve => {
    let form = new FormData;
    // form.append('relativePath', 'null');
    // form.append('name', Math.random() + '.jpg');
    // form.append('type', 'image/jpeg');
    let fstream = fs.createReadStream(file_path);
    fstream.on("error", (err) => {
      return resolve({
        ok: false,
        msg: `file stream error:${err.message}`
      })
    })
    form.append('upfile', fstream, {
      filename: Math.random() + '.jpg',
      contentType: "image/jpeg"
    });
    let uploadEndpoint = "https://www.yuemei.com/c/user/ueuploadShare/type/6?editorid=editor";
    let parsed = url.parse(uploadEndpoint);
    form.submit({
      host: parsed.host,
      path: parsed.path,
      headers: {
        Origin: 'https://www.yuemei.com',
        Referer: 'https://www.yuemei.com/c/8079089.html',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.14 Safari/537.36'
      },
      method: "post",
      protocol: parsed.protocol,
    }, (err, resp) => {
      if (err) {
        return resolve({
          ok: false,
          msg: err.message
        })
      }

      let buf = require("buffer").Buffer.from("");
      resp.on("data", d => {


        buf += d;
      })
      resp.on("end", _ => {
        let str = buf.toString();
        if (resp.statusCode != 200) {
          return resolve({
            ok: false,
            msg: `resp.statusCode=${resp.statusCode}||${str}`
          })
        }
        let matchedScriptTag = str.match(/\<script.*script\>/);
        if (matchedScriptTag && matchedScriptTag.length == 1) {
          let obj = JSON.parse(str.replace(matchedScriptTag[0], ""));
          if (obj.state != "SUCCESS") {
            return resolve({
              ok: false,
              msg: `not success:${str}`
            })
          }
          let image_url = obj.url;
          image_url = image_url.replace(/500_500/, "1000_1000");
          image_url = image_url.replace(/img1\.yuemei\.com/, "p23.yuemei.com");
          return resolve({
            ok: true,
            msg: "ok",
            data: {
              image_url: image_url
            }
          })
          debugger
        } else {
          return resolve({
            ok: false,
            msg: `can't pass RegExp:${str}`
          })
        }
      });
      resp.on("error", (err) => {
        console.log("resp.on error", util.inspect(err));
        return resolve({
          ok: false,
          msg: `resp.on error::${util.inspect(err)}`
        })
      })
    });
    form.on("error", (err) => {
      return resolve({
        ok: false,
        msg: `form.on error:${util.inspect(err)}`
      })
    })
  })
}


/**
  * @returns {Promise<{
  * all_files_count:Number,
  * ok_results:Array<{relative_path:String,link:String}>,
  * error_files:Array<{relative_path:String,msg:String}>
  * }>}
  * @param {String} folder_path 
  */
function uploadAllImagesInFolder(folder_path) {
  return new Promise(async resolve => {
    let o_list = await Toolbox.safeListAllInDir(folder_path);

    let images = o_list.filter(e => {
      let str = e.full_path.toLowerCase();
      return str.endsWith(".jpg")
        || str.endsWith(".jpeg")
        || str.endsWith(".png")
        || str.endsWith(".bmp")
    });
    images = images.filter(e => {
      if (e.stats.isDirectory()) {
        return false;
      }
      if (e.stats.size > 20 * 1024 * 1024) {
        return false;
      }
      return e.stats.isFile();
    })
    if (images.length == 0) {
      return resolve({
        all_files_count: 0,
        ok_results: [],
        error_files: []
      })
    }
    /**
     * @type {Array<{relative_path:String,link:String}>}
     */
    let results = [];
    /**
     * @type {Array<{relative_path:String,msg:String}>}
     */
    let errors = [];
    let tasks = images.map(e => async cb => {
      let try_i = 1;
      let last_error = "";
      while (try_i < 5) {
        try {
          let o_up = await uploadFile(e.full_path);
          if (o_up.ok) {
            results.push({
              relative_path: path.relative(folder_path, e.full_path),
              link: o_up.data.image_url
            })
            return cb();
          } else {
            last_error += o_up.msg + "//\n"
          }
          try_i++;
        } catch (e) {
          console.log("CATCH", e);
          // try_i++;
        }
      }
      errors.push({
        relative_path: path.relative(folder_path, e.full_path),
        msg: last_error
      })
      cb()
    });
    runParallel(tasks, 7, () => {
      results = results.sort((a, b) => a.relative_path.localeCompare(b.relative_path));
      errors = errors.sort((a, b) => a.relative_path.localeCompare(b.relative_path))
      return resolve({
        all_files_count: o_list.length,
        ok_results: results,
        error_files: errors
      })
    })


  })
}
module.exports = {
  uploadFile,
  uploadAllImagesInFolder
}